package org.ccay.web.support.internal.impl;

import java.util.Enumeration;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.ccay.core.log.CcayLoggerFactory;
import org.ccay.core.log.ILogger;
import org.ccay.core.request.impl.RequestContext;
import org.ccay.core.util.StringUtil;
import org.ccay.registry.util.RegistryQueryUtil;

/**
 * 语言辅助类	
 * 
 * @since 2012-4-11
 */
public final class RequestLangUtil {
	/**
	 * 
	 */
	public static final String LANGUAGE_SWITCH = "LanguageSwitch";
	private static final ILogger logger = CcayLoggerFactory.getLogger(RequestLangUtil.class); 
	//Session 中语种的KEY
	private static final String CCAY_LANG = "CCAY_LANG";
	
	
	private RequestLangUtil(){		
	}
	
	public static String getUserLang(HttpServletRequest request){
		//如果不允许语种切换，则直接返回默认语种
		if(!isSwitchEnabled()){
			String lang = getDefaultLang();
			if(!StringUtil.isNullOrEmpty(lang)){
				return lang;
			}
			return "en_US";
		}
		
		 //add 2014-02-26 h00214522 add param 调整为request优先 
		String lang = getLangFromParam(request);
		if(!StringUtil.isNullOrEmpty(lang)){
			setLang2Session(request,lang);
			return lang;
		}
		
		lang = getLangFromSession(request);
		if(!StringUtil.isNullOrEmpty(lang)){
			return lang;
		}
		lang = getDefaultLang();
		if(!StringUtil.isNullOrEmpty(lang)){
			return lang;
		}
		lang = getLangFromBrowser(request);		
		if(!StringUtil.isNullOrEmpty(lang)){
			setLang2Session(request,lang);
			return lang;
		}
		return "en_US";
	}

	/** 
	 * 是否允许语种切换
	 * @return
	 */
	public static boolean isSwitchEnabled() {
		return RegistryQueryUtil.getBooleanValue("Ccay.GlobalParamters.LanguageSwitch");
	}

	/** 
	 * 从浏览器首选项获取语种
	 * @param request
	 * @return
	 */
	private static String getLangFromBrowser(HttpServletRequest request) {		
		for (Enumeration<Locale> locales = request.getLocales(); locales.hasMoreElements() ;) {
			Locale locale = locales.nextElement();
			String lang = locale.getLanguage() +"_" + locale.getCountry();
			if(isValidLang(lang)){
				logger.debug("Locale got from browser: {0}", lang);
				return lang;
			}
		}
		
		return "en_US";
	}
	/**
	 * TODO  add url language	
	 * 
	 * @since 2013-12-23
	 * @param request
	 * @return
	 */
	private static String getLangFromParam(HttpServletRequest request){
		String lang = request.getParameter("locale");
		if(!StringUtil.isNullOrEmpty(lang) && isValidLang(lang)){
			return lang;
		}
		return null;
	}
	/** 
	 * @param request
	 * @param lang
	 */
	private static void setLang2Session(HttpServletRequest request, String lang) {
		if (! isValidLang(lang)){
			return;
		}

		RequestUtil.setSessionValue(request, CCAY_LANG, lang);
	}

	/** 
	 * @param request
	 * @param lang
	 */
	public static void setLang2Session(String lang) {
		if (! isValidLang(lang)){
			return;
		}
		
		RequestContext request = (RequestContext)RequestContext.getCurrent();
		request.getSession().put(CCAY_LANG,lang); 
		request.setUserLanguage(lang);
	}

	/** 
	 * 是否有效语种
	 * @param lang
	 * @return
	 */
	public static boolean isValidLang(String lang) {
		String[] langs = getValidLanguages();
		for(String validLang : langs){
			if( lang.equalsIgnoreCase((validLang))){
				return true;
			}
		}
		
		return false;
	}

	/** 
	 * 获取有效语种
	 * @return
	 */
	public static String[] getValidLanguages() {
		return RegistryQueryUtil.getValue("Ccay.GlobalParamters.ValidLanguages").split(",");
	}

	/** 
	 * 
	 * @return
	 */
	private static String getDefaultLang() {
		return RegistryQueryUtil.getValue("Ccay.GlobalParamters.DefaultLanguage");
	}

	/** 
	 * @param session
	 */
	private static String getLangFromSession(HttpServletRequest request) {
		//Use Shior Session
		//HttpSession session = request.getSession(false);
		Session session = SecurityUtils.getSubject().getSession(false);
		if(session== null){
			 return null;
		}
		Object sessionLang = session.getAttribute(CCAY_LANG);
		 if(sessionLang != null){
			 return (String)sessionLang;
		 }
		 
		 return null;
	}
	
	/** 
	 * 切换语种
	 * @param request
	 * @param response
	 * @param lang
	 */
	public static void swithTo(HttpServletRequest request,  HttpServletResponse response, String lang){
		//设置Session语种
		setLang2Session(request, lang);
	}
}
